package org.john.auth.client.util;

import java.security.Key;
import java.util.Base64;
import java.util.Date;

import org.apache.commons.lang3.SerializationUtils;
import org.john.auth.client.context.UserContext;
import org.john.common.util.HexUtil;
import org.john.common.util.SpringUtil;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class JwtTokenUtil {

	public static final long DEFAULT_EXPIRE = 60 * 60; // 默认token过期时长,单位秒
	public static final long DEFAULT_EXPIRE_REFRESH_TOKEN = 60 * 60 * 24 * 30 * 3; // 默认refresh_token过期时长,单位秒

	private final static String KEY_JWTKEY = "jwt.key";

	/**
	 * 生成token
	 *
	 * @param userContext 载体
	 * @return Token
	 */
	public static String buildToken(UserContext userContext) {
		Date expireDate = new Date(userContext.getExpireTime());
		// 生成access_token
		byte[] userContextSer = SerializationUtils.serialize(userContext);
		String userContextStr = Base64.getEncoder().encodeToString(userContextSer);
		return Jwts.builder().setSubject(userContextStr).signWith(getKey()).setExpiration(expireDate).compact();
	}

	/**
	 * 解析token
	 *
	 * @param token token
	 * @return Claims
	 */
	private static Claims parseToken(String token) {
		Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKey()).parseClaimsJws(token);
		return claimsJws.getBody();
	}

	public static UserContext paseUserContext(String token) {
		String userContextStr = parseToken(token).getSubject();
		byte[] userContextSer = Base64.getDecoder().decode(userContextStr);
		return SerializationUtils.deserialize(userContextSer);
	}

	public static UserContext paseUserContext(Claims claims) {
		String userContextStr = claims.getSubject();
		byte[] userContextSer = Base64.getDecoder().decode(userContextStr);
		return SerializationUtils.deserialize(userContextSer);
	}

	/**
	 * 把16进制的key解析成Key
	 *
	 * @return Key
	 */
	public static Key getKey() {
		String hexKey = SpringUtil.getProperty(KEY_JWTKEY);
		return parseHexKey(hexKey);
	}

	private static Key parseHexKey(String hexKey) {
		if (hexKey == null || hexKey.trim().isEmpty()) {
			return null;
		}
		return Keys.hmacShaKeyFor(HexUtil.decode(hexKey));
	}

	public static void main(String[] args) {
		System.out.println(HexUtil.encodeToString(Keys.secretKeyFor(SignatureAlgorithm.HS256).getEncoded()));
	}

}